package cn.com.controller.wxController;

import java.math.BigDecimal;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.com.Enum.OrderStatus;
import cn.com.constant.Code;
import cn.com.db.model.DiyOrder;
import cn.com.db.model.Order;
import cn.com.db.model.OrderItem;
import cn.com.db.model.WxPayResult;
import cn.com.db.service.OrderService;
import cn.com.db.service.WxPayResultService;
import cn.com.util.DataResult;
import cn.com.util.IpUtil;
import cn.com.util.JsonUtil;
import cn.com.util.TimeUtil;
import cn.com.util.UidUtil;
import cn.com.wxUtil.HttpUtil;
import cn.com.wxUtil.PayCommonUtil;
import cn.com.wxUtil.PayUtil;
import cn.com.wxUtil.ReturnSignUtil;
import cn.com.wxUtil.XMLUtil;
import cn.com.wxUtil.wxConstant;
import cn.com.wxUtil.refundUtil.WXUtil;

/**
 * 微信支付返回前端五个所需参数,前端小程序用这五个参数调用微信支付功能 之后微信回调PayNotifyController
 * 
 * @author mxq
 */
@RestController
@RequestMapping("/wx/")
public class ReturnOrderSignController {
	@Autowired
	OrderService orderService;
	@Autowired
	WxPayResultService wxPayResultService;

	// 微信下单支付
	@RequestMapping("doOrder")
	public String doOrder(HttpServletRequest request, HttpServletResponse response,
			@RequestParam("orderId") String orderIdList, @RequestParam("code") String code // 临时登陆凭证,前端请求微信服务器获取
	) throws Exception {
		DataResult dataResult = new DataResult();
		if (StringUtils.isEmpty(orderIdList)) {
			dataResult.setCode(Code.ERRORPARM);
			dataResult.setMessage("订单id不能为空");
			return JsonUtil.toJsonString(dataResult);
		}
		// 先登陆 获取openid,session_key
		String openid = "";
		String session_key = ""; // 会话密钥session_key 是对用户数据进行加密签名的密钥(暂时没用)
		String url = "https://api.weixin.qq.com/sns/jscode2session";
		String httpUrl = url + "?appid=" + wxConstant.APPID + "&secret=" + wxConstant.SECRET + "&js_code=" + code
				+ "&grant_type=authorization_code";
		String ret = cn.com.util.HttpUtil.doGet(new URL(httpUrl)); // 这里工具类名称重复了
		JSONObject obj = JSONObject.parseObject(ret);
		if (obj.containsKey("errcode")) {
			String errmsg = obj.get("errmsg").toString();
			dataResult.setCode(Code.ERRORPARM);
			dataResult.setData(errmsg);
			dataResult.setMessage("code错误或失效");
			return JsonUtil.toJsonString(dataResult);
		} else if (obj.containsKey("session_key")) {
			// 开始处理userInfo
			openid = obj.get("openid").toString();
			session_key = obj.get("session_key").toString();
		}

		// 登陆结束
		StringBuffer bodyBuffer = new StringBuffer("");
		// 分割订单 同一家商店配送费价格不能重复计算
		BigDecimal price = new BigDecimal("0.00");
		List<String> idList = UidUtil.splitStringByLine(orderIdList);
		Set<String> stores = new HashSet<>();
		List<Order> orderList = orderService.getOrderByIdList(idList);
		for (Order order : orderList) {
			List<OrderItem> items = order.getItems();
			for (OrderItem item : items) {
				bodyBuffer.append(item.getGoodsName()).append(",");
			}
			price = order.getPrice().add(price);
			String store = order.getStore();
			if (!stores.contains(store)) {
				stores.add(store);
				if (order.getFreight() != null) {
					price = order.getFreight().add(price);
				}
			}
		}
		String body = bodyBuffer.substring(0,bodyBuffer.length()-1);

		String priceString = String.valueOf(price.movePointRight(2).intValue());
		System.out.println(priceString);
		// 时间戳
		String nonce_str = UidUtil.createUUID();
		String ip = request.getRemoteAddr();
		String xprId = UidUtil.createUUID(); // 创建微信支付商户订单号
		SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
		packageParams.put("appid", wxConstant.APPID);
		packageParams.put("mch_id", wxConstant.MCH_ID);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("body", body);// 支付主体
		packageParams.put("out_trade_no", xprId);// 订单编号
		packageParams.put("total_fee", priceString);// 价格 这里要是字符串
		packageParams.put("spbill_create_ip", ip); // 这里加了客户端ip
		packageParams.put("notify_url", "http://118.24.106.223:8080/wx/wxPayNotify/order");// 支付结束微信服务器回调地址
																						// 118.24.106.223:8080
		packageParams.put("trade_type", "JSAPI");// 这个api有，固定的
		packageParams.put("openid", openid);// openid

		String mysign = PayCommonUtil.createSign("UTF-8", packageParams, wxConstant.PAY_KEY); // 最后这个是自己设置的32位密钥
		packageParams.put("sign", mysign);

		// 转成XML
		String xml = "<xml>" + "<appid>" + wxConstant.APPID + "</appid>" + "<body><![CDATA[" + body
				+ "]]></body>" + "<mch_id>" + wxConstant.MCH_ID + "</mch_id>" + "<nonce_str>" + nonce_str
				+ "</nonce_str>" + "<notify_url>" + "http://118.24.106.223:8080/wx/wxPayNotify/order" + "</notify_url>"
				+ "<openid>" + openid + "</openid>" + "<out_trade_no>" + xprId + "</out_trade_no>"
				+ "<spbill_create_ip>" + ip + "</spbill_create_ip>" + "<total_fee>" + priceString + "</total_fee>"
				+ "<trade_type>" + "JSAPI" + "</trade_type>" + "<sign>" + mysign + "</sign>" + "</xml>";
		String result = PayUtil.httpRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", xml);
		System.out.println(result);
		// 解析XML存入Map
		// Map map = XMLUtil.doXMLParse(resXml);
		Map map = PayUtil.doXMLParse(result);
		// 得到prepay_id
		String prepay_id = (String) map.get("prepay_id");

		SortedMap<Object, Object> packageP = new TreeMap<Object, Object>();
		if (StringUtils.isNotEmpty(prepay_id)) {

			// 数据库表中初步添加数据
			WxPayResult wxPayResult = new WxPayResult();

			wxPayResult.setId(xprId);
			wxPayResult.setOrder_id(orderIdList);
			wxPayResult.setCreated_at(TimeUtil.getNowTimestamp());
			wxPayResult.setUpdated_at(TimeUtil.getNowTimestamp());
			wxPayResult.setResult(OrderStatus.WAIT_PAY.getStatus());
			wxPayResult.setPrepay_id(prepay_id);
			// wxPayResult表没有存微信服务器内部的订单id,只有自己这个xprId,可能需要加字段
			wxPayResultService.createWxPayResult(wxPayResult);

			packageP.put("appId", wxConstant.APPID);// ！！！注意，这里是appId,上面是appid，写这个东西的人。。。
			packageP.put("nonceStr", nonce_str);
			packageP.put("package", "prepay_id=" + prepay_id);// 必须把package写成
																// "prepay_id="+prepay_id这种形式
			packageP.put("signType", "MD5");// paySign加密
			packageP.put("timeStamp", (System.currentTimeMillis() / 1000) + "");// 时间戳
			// 得到paySign
			String paySign = PayCommonUtil.createSign("UTF-8", packageP, wxConstant.PAY_KEY);
			packageP.put("paySign", paySign);
		} else {
			dataResult.setData(packageP);
			dataResult.setCode(Code.ERRORPARM);
			dataResult.setMessage("获取微信prepay_id失败");
			return JsonUtil.toJsonString(dataResult);
		}
		// 将packageP数据返回给小程序
		dataResult.setData(packageP);
		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("获取成功");
		return JsonUtil.toJsonString(dataResult);
	}
}
